package MineSweeper;

public class MineMap {
	// an integer array which used to store mine's locations 
	private int[][] mineLocation;
	// grid length
	int length;
	// grid width
	int width;
	// mine number
	int mineNumber;
	
	/**
	 * constructor
	 * @param length :input grid length
	 * @param width :input grid width
	 * @param mineNumber :input mine number
	 */
	public MineMap(int length, int width, int mineNumber){
		// set grid length
		this.length = length;
		// set grid width
		this.width = width;
		// set mine number
		this.mineNumber = mineNumber;
		// Initialize the array with default value -2, which stands for unknown locations.
		// the array mineLocation has some position not played in the game, however this position will help the game to count mine number
		// Basically, the useful information are stored from length 1 to 'length', width 1 to 'width', the value for other position in this
		// array will always be the initial value -2.
		mineLocation = new int[length+2][width+2];
		for(int i = 0; i <= length+1; i++){
			for(int j = 0; j <= width+1; j++){
				mineLocation[i][j] = -2;
			}
		}
		// call the setMineLocation method to set mines' location
		setMineLocation();
		fillAll();
	}
	
	/**
	 *  method setMineLocation is used to set Mine's locations. Basically, it random a set of different integer numbers
	 *  within the range of array mineLocation.length() and set the value of this locations in array mineLocation to -1
	 *  which stands for mines.
	 */
	private void setMineLocation(){
		int count = 0;
		while(count < mineNumber){
			// random a number in the range [0,length]
			int temp1 = (int) Math.round(Math.random()*length);
			// random a number in the range [0,width]
			int temp2 = (int) Math.round(Math.random()*width);
			// check if the number is already selected and is the position stored useful information (should not contain array[0][m] array[n][0])
			if( (mineLocation[temp1][temp2] != -1) && (temp1*temp2 != 0)){
				// set the value to -1, stands for mine
				mineLocation[temp1][temp2] = -1;
				count++;
			}
		}
		
	}
	
	/**
	 * Fill all the other position after set mines' location
	 */
	private void fillAll(){
		// outer loop change the column number
		for(int i = 1; i <= length; i++){
			// inner loop change the row number
			for(int j =1; j <= width; j++){
				if(mineLocation[i][j] == -2){
					mineLocation[i][j] = 0;
					if(mineLocation[i-1][j-1] == -1){
						mineLocation[i][j]++;
					}
					if(mineLocation[i][j-1] == -1){
						mineLocation[i][j]++;
					}
					if(mineLocation[i+1][j-1] == -1){
						mineLocation[i][j]++;
					}
					if(mineLocation[i-1][j] == -1){
						mineLocation[i][j]++;
					}
					if(mineLocation[i+1][j] == -1){
						mineLocation[i][j]++;
					}if(mineLocation[i-1][j+1] == -1){
						mineLocation[i][j]++;
					}
					if(mineLocation[i][j+1] == -1){
						mineLocation[i][j]++;
					}if(mineLocation[i+1][j+1] == -1){
						mineLocation[i][j]++;
					}
					
				}
			}
		}
		
	}
	
	public void printMap(){
		for(int j = 1; j <= width; j++){
			for(int i = 1; i <= length; i++){
				System.out.print(mineLocation[i][j]+ " ");
			}
			System.out.println("");
		}
	}
	
	public int getLocation(int number){
		return mineLocation[mod(number,length) + 1][((number+length) / length)];
	}
	
	private int mod(int m, int n){
		if(m < 0){
			return (-((-m) % n));
		}else{
			return (m%n);
		}
	}

}
